<?php
/**
 * 数据备份
 * User 1874
 */
namespace app\adminplatform\controller;
use app\adminplatform\model\AuthGroup;
use app\common\controller\Backup as BackupClass;
use think\facade\Request;
use think\facade\Session;
use think\facade\View;

class Backup extends Initial {
    /**
     * 备份数据表列表
     */
    public function backList(){
        $db = new BackupClass();
        //管理员权限
        $rules = ['Backup/export', 'Backup/repair', 'Backup/optimize'];
        $check = AuthGroup::checkMethodArray(Session::get('userData'), $rules);

        View::assign('info', $db->dataList());
        View::assign('check', $check);
        return View::fetch('backList');
    }
    /**
     * 备份方法
     */
    public function export(){
        $db = new BackupClass();
        if(Request::isPost()){
            $input = Request::post();
            $fileinfo = $db->getFile();
            //检查是否有正在执行的任务
            $lock = "{$fileinfo['filepath']}backup.lock";
            if(is_file($lock)){
                return json(["info"=>"检测到有一个备份任务正在执行，请稍后再试", "status"=>0]);
            } else {
                //创建锁文件
                file_put_contents($lock, time());
            }
            // 检查备份目录是否可写
            //if(is_writeable($fileinfo['filepath'])){
            //    return json(["info"=>"备份目录不存在或不可写，请检查后重试", "status"=>0, "path"=>$fileinfo['filepath']]);
            //}
            //缓存锁文件
            Session::set('lock', $lock);
            //缓存备份文件信息
            Session::set('backup_file', $fileinfo['file']);
            //缓存要备份的表
            Session::set('backup_tables', $input['tables']);
            //创建备份文件
            if(false !== $db->Backup_Init()){
                $data = ["info"=>"初始化成功", "status"=>1, 'tab'=>['id' => 0, 'start' => 0]];
            }else{
                $data = ["info"=>"初始化失败", "status"=>0];
            }
        }else if(Request::isGet()){
            $tables =  Session::get('backup_tables');
            $file = Session::get('backup_file');
            $id = Request::get('id');
            $start = Request::get('start');
            $start = $db->setFile($file)->backup($tables[$id], $start);
            if(false === $start){
                $data = ["info"=>"备份出错", "status"=>0];
            }else if(0 === $start){
                if(isset($tables[++$id])){
                    $tab = array('id' => $id, 'start' => 0);
                    $data = ["info"=>"备份完成", "status"=>1, "tab"=>$tab];
                } else { //备份完成，清空缓存
                    unlink(Session::get('lock'));
                    Session::delete('backup_tables');
                    Session::delete('backup_file');
                    $data = ["info"=>"备份完成", "status"=>1];
                }
            }
        }else{
            $data = ["info"=>"参数错误", "status"=>0];
        }
        return json($data);
    }
    /**
     * 修复表
     */
    public function repair($tables= null){
        if(Request::isPost()){
            $db = new BackupClass();
            if($db->repair($tables)){
                $data = ["info"=>"数据表修复完成", "status"=>1];
            }else{
                $data = ["info"=>"数据表修复出错请重试", "status"=>0];
            }
        }else{
            $data = ["info"=>"请求类型错误", "status"=>0];
        }
        return json($data);
    }
    /**
     * 优化表
     */
    public function optimize($tables= null){
        if(Request::isPost()) {
            $db = new BackupClass();
            if ($db->optimize($tables)) {
                $data = ["info" => "数据表优化完成", "status" => 1];
            } else {
                $data = ["info" => "数据表优化出错请重试", "status" => 0];
            }
        }else{
            $data = ["info"=>"请求类型错误", "status"=>0];
        }
        return json($data);
    }
//================================================================【备份还原】=============================================================
    /**
     * 备份文件列表
     */
    public function importList(){
        $db = new BackupClass();
        //管理员权限
        $rules = ['Backup/import', 'Backup/down', 'Backup/del'];
        $check = AuthGroup::checkMethodArray(Session::get('userData'), $rules);

        View::assign('info', $db->fileList());
        View::assign('check', $check);
        return View::fetch('importList');
    }
    /**
     * 备份文件还原方法
     */
    public function import($time = 0, $part = null, $start = null){
        $db= new BackupClass();
        if(is_numeric($time) && is_null($part) && is_null($start)){
            $list = $db->getFile('timeverif', $time);
            if(is_array($list)){
                session::set('backup_list', $list);
                $data = ["info"=>"初始化完成", "status"=>1, "data"=>['part' => 1, 'start' => 0]];
            }else{
                $data = ["info"=>"备份文件可能已经损坏，请检查", "status"=>0];
            }
        }else if(is_numeric($part) && is_numeric($start)){
            $list = session::get('backup_list');

            $start= $db->setFile($list)->import($start);

            if(false===$start){
                $data = ["info"=>"还原数据出错", "status"=>0];
            }elseif(0 === $start){
                if(isset($list[++$part])){
                    $data = ["info"=>"正在还原", "status"=>1, "data"=>['part' => $part, 'start' => 0]];
                } else {
                    session::delete('backup_list');
                    $data = ["info"=>"还原完成", "status"=>1];
                }
            }else{
                $output = array('part' => $part, 'start' => $start[0]);
                if($start[1]){
                    $rate = floor(100 * ($start[0] / $start[1]));
                    $data = ["info"=>"正在还原({$rate}%)", "status"=>1, "data"=>$output];
                } else {
                    $data['gz'] = 1;
                    $data = ["info"=>"正在还原", "status"=>1, "data"=>$output];
                }
            }
        }else{
            $data = ["info"=>"参数错误", "status"=>0];
        }
        return json($data);
    }
    /**
     * 删除备份文件
     */
    public function del($time = 0){

        if(Request::isPost()) {
            $db = new BackupClass();
            if($db->delFile($time)){
                $data = ["info"=>"备份文件删除成功", "status"=>1];
            }else{
                $data = ["info"=>"备份文件删除失败", "status"=>0];
            }
        }else{
            $data = ["info"=>"请求类型错误", "status"=>0];
        }
        return json($data);
    }
    /**
     * 下载备份文件
     */
    public function down($time = 0){
        $db= new BackupClass();
        $db->downloadFile($time);
    }
}